package gui;

import java.awt.*;
import java.util.Date;

import javax.swing.JLabel;
import javax.swing.JTextField;

import main.DoubleArrayGrid;
import main.FloatArrayGrid;
import main.FloatObjArrayGrid;
import main.TwoDGrid;
import main.XYCoordinate;
import main.DoubleObjectGrid;

/**
 *
 * @author Arwa Tyebkhan
 */
public class HeatGrid extends Component {
  public static final int GRID_COORD_SIZE = 400;
  
  private final float RED_FACTOR = 2.5F; 
  private int size;
  private int gridDimensions;
  private TwoDGrid grid;
  private int maxCount;
  
  /** Creates a new instance of HeatGrid */
  public HeatGrid(int size, int max) {
    setSize(size);
    this.maxCount = max;
    setSize(GRID_COORD_SIZE, GRID_COORD_SIZE);
  }
  
  public void run(TwoDGrid grid, boolean animate, JTextField counter) {
    this.grid = grid;
    int count = 0;
	
    long start = new Date().getTime();
//    long memoryStart = Runtime.getRuntime().freeMemory();
//    long memStart = Runtime.getRuntime().totalMemory() -Runtime.getRuntime().freeMemory(); 
    if(animate) {
      do {
        this.grid.stepGrid();
        count++;
        paint(getGraphics());
//        counter.setText(String.valueOf(count));
//        counter.update(counter.getGraphics());
      } while((!grid.isDone()) && (count < maxCount));
    }
    else {
      do {
        this.grid.stepGrid();
        count++;
      } while((!grid.isDone()) && (count < maxCount));
      repaint();
    }    
//    long memEnd = Runtime.getRuntime().totalMemory() -Runtime.getRuntime().freeMemory();
//    long memoryEnd = Runtime.getRuntime().freeMemory();
//    long memoryUsed = memoryStart - memoryEnd;
    long end = new Date().getTime();
//    TwoDGrid.printResults(grid.getGridSizeX() + 1, grid);
//    double runTime = ((end-start) / 1000d);
//    System.out.println("Run time: "+runTime+" secs");
//    System.out.println("Memory used: "+memoryUsed);
//    System.out.println("Memory used: "+ (memStart-memEnd));
    
  }

  public void setSize(int size) {
    this.size = size;
    
    gridDimensions = GRID_COORD_SIZE / size;
//    int shrinkedGrid = gridDimensions * size;
//    int extraPixels = GRID_COORD_SIZE - shrinkedGrid;
//    int extraPixelPerCell;
//    if(extraPixels > 0) 
//      extraPixelPerCell= size / extraPixels;
//    else
//      extraPixelPerCell = 0;
//    gridDimensions +=  extraPixelPerCell;
  }
  public void setMaxCount(int max) {
    this.maxCount = max;
  }

  public void paint(Graphics g) {
    if (grid != null) {
      if(grid instanceof DoubleArrayGrid) {
        daPaintCellColor(g, gridDimensions);
      }
      else if(grid instanceof FloatArrayGrid) {
        faPaintCellColor(g, gridDimensions);
      }
      else if(grid instanceof FloatObjArrayGrid) {
        faObjPaintCellColor(g, gridDimensions);
      } 
      else if(grid instanceof DoubleObjectGrid) {
    	  doPaintCellColor(g, gridDimensions);
      }
    }
    else {
      g.setColor(Color.BLACK);
      for (int i = 0; i < GRID_COORD_SIZE; i = i + gridDimensions) {
        for (int j = 0; j < GRID_COORD_SIZE; j = j + gridDimensions) {
          g.fillRect(i, j, gridDimensions, gridDimensions);
        }
      }
    }
  }
  
  private void daPaintCellColor(Graphics g, int dim) {
    int cellX=0, cellY=0;
    for (int x = 1; x <= size; x++) {      
      for (int y = 1; y <= size; y++) {
        double newTemp = grid.getDoubleValue(new XYCoordinate(x, y)) * RED_FACTOR;
        int shadeOfRed = new Double(newTemp).intValue();
//        System.out.print("\n["+x+", "+y+"] color: " + shadeOfRed);
        g.setColor(new Color(shadeOfRed, 0, 0));
        g.fillRect(cellX, cellY, dim, dim);
        cellY += dim;
      }      
      cellX += dim;
      cellY = 0;
    }
  }
  
  private void faPaintCellColor(Graphics g, int dim) {
    int cellX=0, cellY=0;
    for (int x = 1; x <= size; x++) {      
      for (int y = 1; y <= size; y++) {
        float newTemp = grid.getFloatValue(new XYCoordinate(x, y)) * RED_FACTOR;
        int shadeOfRed = new Float(newTemp).intValue();
//        System.out.print("\n["+x+", "+y+"] color: " + shadeOfRed);
        g.setColor(new Color(shadeOfRed, 0, 0));
        g.fillRect(cellX, cellY, dim, dim);
        cellY += dim;
      }      
      cellX += dim;
      cellY = 0;
    }
  }
  
  private void faObjPaintCellColor(Graphics g, int dim) {
    int cellX=0, cellY=0;
    for (int x = 1; x <= size; x++) {      
      for (int y = 1; y <= size; y++) {

        float newTemp = grid.getFloatObjValue(new XYCoordinate(x, y)).floatValue() * RED_FACTOR;
        int shadeOfRed = new Float(newTemp).intValue();
//        System.out.print("\n["+x+", "+y+"] color: " + shadeOfRed);
        g.setColor(new Color(shadeOfRed, 0, 0));
        g.fillRect(cellX, cellY, dim, dim);
        cellY += dim;
      }      
      cellX += dim;
      cellY = 0;
    }
  }  

  private void doPaintCellColor(Graphics g, int dim) {
    int cellX=0, cellY=0;
    for (int x = 1; x <= size; x++) {      
      for (int y = 1; y <= size; y++) {

        double newTemp = grid.getDoubleValue(new XYCoordinate(x, y)) * RED_FACTOR;
        int shadeOfRed = new Double(newTemp).intValue();
//        System.out.print("\n["+x+", "+y+"] color: " + shadeOfRed);
        g.setColor(new Color(shadeOfRed, 0, 0));
        g.fillRect(cellX, cellY, dim, dim);
        cellY += dim;
      }      
      cellX += dim;
      cellY = 0;
    }
  }

}